package com.xlinur.android.moviecatalog;

import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Map;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;

public class MovieExportCSV extends Activity {
	private static final int FILE_CHOOSE = 1;
	private static final int DIALOG_PROGRESS = 1;
	private static ProgressDialog mDialog;
	private static String mFilename;
	private static boolean mAddTitles;
	private static String mDivider;
	private static String mEncoding;
	private static BufferedWriter mFile;
	private static Button eButtonExport;
	private static Button eButtonCancel;
	private static EditText eFilename;
	private static Spinner eDivider;
	private static Spinner eEncoding;
	private static CheckBox eAddTitles;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.movie_export_csv);
		eFilename = (EditText) findViewById(R.id.csvEditText_filename);
		eDivider = (Spinner) findViewById(R.id.csvSpinner_divider);
		eEncoding = (Spinner) findViewById(R.id.csvSpinner_encoding);
		eAddTitles = (CheckBox) findViewById(R.id.csvCheckBox_titles);
		eButtonExport = (Button) findViewById(R.id.csvButtonExport);
		eButtonCancel = (Button) findViewById(R.id.csvButtonCancel);

		eButtonExport.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				onExportButtonClicked();
			}
		});
		eButtonCancel.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				finish();
			}
		});
		eFilename.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Intent viewActivity = new Intent(getBaseContext(),
						FileBrowser.class);
				viewActivity.putExtra("file", eFilename.getText().toString());
				startActivityForResult(viewActivity, FILE_CHOOSE);
			}
		});
		getPrefs();
		fillFields();
	}

	@Override
	public void onStart() {
		super.onStart();
	}

	@Override
	public void onStop() {
		super.onStop();
		if (mFile != null) {
			try {
				mFile.close();
			} catch (IOException e) {

			}
		}
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode == Activity.RESULT_OK && requestCode == FILE_CHOOSE) {
			String filename = data.getStringExtra("file");
			if (filename != null) {
				mFilename = filename;
				eFilename.setText(mFilename);
			}
		}
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		super.onCreateDialog(id);
		switch (id) {
		case DIALOG_PROGRESS:
			ProgressDialog dialog = new ProgressDialog(this);
			dialog.setTitle(R.string.export_csv_progress_title);
			dialog.setMessage("");
			dialog.setIndeterminate(true);
			dialog.setCancelable(true);
			mDialog = dialog;
			return dialog;
		default:
			return null;
		}
	}

	private void fillFields() {
		eFilename.setText(mFilename);
		eAddTitles.setChecked(mAddTitles);
		String[] dividers = getResources().getStringArray(R.array.csvDivider);
		int count = dividers.length;
		for (int i = 0; i < count; i++) {
			if (dividers[i].equals(mDivider)) {
				eDivider.setSelection(i);
			}
		}
		String[] encoding = getResources().getStringArray(R.array.encoding);
		count = encoding.length;
		for (int i = 0; i < count; i++) {
			if (encoding[i].equals(mEncoding)) {
				eEncoding.setSelection(i);
			}
		}
	}

	private void getPrefs() {
		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(getBaseContext());
		mFilename = prefs.getString("csvExportFilename", "");
		mAddTitles = Boolean.parseBoolean(prefs.getString("csvExportAddTitles", "false"));
		mDivider = prefs.getString("csvExportDivider", getResources()
				.getStringArray(R.array.csvDivider)[0]);
		mEncoding = prefs.getString("csvExportEncoding", getResources()
				.getStringArray(R.array.encoding)[2]);
	}

	private void setPrefs() {
		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(getBaseContext());
		SharedPreferences.Editor editor = prefs.edit();
		editor.putString("csvExportFilename", eFilename.getText().toString());
		editor.putString("csvExportAddTitles", Boolean.toString(eAddTitles.isChecked()));
		editor.putString("csvExportDivider", eDivider.getSelectedItem()
				.toString());
		editor.putString("csvExportEncoding", eEncoding.getSelectedItem()
				.toString());
		editor.commit();
	}

	private void onExportButtonClicked() {
		setPrefs();
		showDialog(DIALOG_PROGRESS);

		new Thread(new Runnable() {
			public void run() {
				final boolean complete = runExport();
				MovieExportCSV.this.runOnUiThread(new Runnable() {
					public void run() {
						dismissDialog(DIALOG_PROGRESS);
						if (complete) {
							Toast.makeText(getApplicationContext(),
									R.string.export_success,
									MovieCatalog.MESSAGE_TIME).show();
						} else {
							Toast.makeText(getApplicationContext(),
									R.string.export_fail,
									MovieCatalog.MESSAGE_TIME).show();
						}
						finish();
					}
				});
			}
		}).start();
	}
	
	private String getCsvItem(String str, String divider){
		String item = str;
		if (item == null) {
			item = "";
		}
		item = item.replaceAll("\"", "\"\"");
		if (item.contains(divider) || item.contains("\"")) {
			item = "\"" + item + "\"";
		}
		return item;
		
	}
	
	private String getMovieString(Map<String, String> movie) {
		int count = MovieCatalog.MovieOrder.length;
		String divider = eDivider.getSelectedItem().toString();
		String result = "";
		for (int i = 0; i < count; i++) {
			String item = movie.get(MovieCatalog.MovieOrder[i]);
			if (i != 0) {
				result += divider;
			}
			result += getCsvItem(item,divider);
		}
		return result;
	}

	private String getMovieTitles() {
		int count = MovieCatalog.MovieOrder.length;
		String[] titles = getResources().getStringArray(R.array.movie);
		String divider = eDivider.getSelectedItem().toString();
		String result = "";
		for (int i = 0; i < count; i++) {
			String item = titles[i];
			if (i != 0) {
				result += divider;
			}
			result += getCsvItem(item,divider);
		}
		return result;
	}
	
	
	
	private boolean runExport() {
		boolean flag = false;
		int success = 0;
		int fail = 0;
		try {
			mFile = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(mFilename), eEncoding
							.getSelectedItem().toString()));
			flag = true;
		} catch (SecurityException e) {
			Toast.makeText(
					getApplicationContext(),
					getString(R.string.file_io_error_write).replace("{1}",
							mFilename), MovieCatalog.MESSAGE_TIME).show();
		} catch (UnsupportedEncodingException e) {
			Toast.makeText(
					getApplicationContext(),
					getString(R.string.encoding_error)
							.replace("{1}", mFilename),
					MovieCatalog.MESSAGE_TIME).show();
		} catch (FileNotFoundException e) {
			Toast.makeText(
					getApplicationContext(),
					getString(R.string.file_not_found)
							.replace("{1}", mFilename),
					MovieCatalog.MESSAGE_TIME).show();
		}
		if (flag) {
			ArrayList<String> ids = MovieCatalog.db.getAllIds();
			int count = ids.size();
			if (eAddTitles.isChecked()) {
				try {
					mFile.write(getMovieTitles());
				} catch (IOException e) {
				}
			}
			for (int i = 0; i < count; i++) {
				try {
					Map<String, String> movie = MovieCatalog.db.getMovie(ids.get(i));
					if (i != 0 || eAddTitles.isChecked()) {
						mFile.newLine();
					}
					mFile.write(getMovieString(movie));
					success++;
				} catch (IOException e) {
					fail++;
				}
				final String progressMessage = getString(
						R.string.export_csv_progress_message).replace("{1}",
						String.valueOf(success)).replace("{2}",
						String.valueOf(fail));
				MovieExportCSV.this.runOnUiThread(new Runnable() {
					public void run() {
						if (mDialog != null && mDialog.isShowing()) {
							mDialog.setMessage(progressMessage);
						}
					}
				});
			}
		}
		return flag;
	}
}
